/*
Copyright (C) 2022-2024 Inspur Corp. All Rights Reserved.

SPDX-License-Identifier: Apache-2.0
*/
package rdb

import (
	"fmt"
	"strings"
	"time"

	"github.com/go-redis/redis"
)

const (
	LockSuffix    = "_account_locked"
	RetrySuffix   = "_account_retry"
	MaxRetry      = 5
	RetryDuration = 5 * time.Minute
	LockDuration  = time.Hour
)

type LockTool struct {
	client *redis.Client
}

func NewLockTool() *LockTool {
	return &LockTool{
		client: GetRedisClient(),
	}
}

func (tool *LockTool) IsAccountLocked(account string) (isLocked bool, lockMsg string) {
	tool.client.SetNX(account+LockSuffix, 0, 5*time.Second)
	il, err := tool.client.Get(account + LockSuffix).Int()
	if err != nil {
		log.Errorf("is locked error: %v", err)
		return
	}
	isLocked = il == 1
	if !isLocked {
		return
	}
	ttl, err := tool.client.TTL(account + LockSuffix).Result()
	minutes, seconds := getTimeValues(ttl)
	lockMsg = fmt.Sprintf("账号已被锁定，请于%s分%s秒后重新尝试！", minutes, seconds)
	return
}

func (tool *LockTool) HandleLoginFailed(account string) {
	// 如果重试次数不存在，设置其为0
	err := tool.client.SetNX(account+RetrySuffix, 0, RetryDuration).Err()
	if err != nil {
		log.Errorf("set retry count error: %v", err)
		return
	}
	errorCount, err := tool.client.Incr(account + RetrySuffix).Result()
	if err != nil {
		log.Errorf("handle login failed error: %v", err)
		return
	}
	if errorCount >= MaxRetry {
		err := tool.client.Set(account+LockSuffix, 1, LockDuration).Err()
		if err != nil {
			log.Errorf("set lock flag error: %v", err)
			return
		}
	}
}

func (tool *LockTool) HandleLoginSuccess(account string) {
	tool.client.Del(account + RetrySuffix)
}

func getTimeValues(remainingTime time.Duration) (string, string) {
	remainingTimeString := remainingTime.String()
	mIndex := strings.Index(remainingTimeString, "m")
	var minutes string
	if mIndex > 0 {
		minutes = remainingTimeString[:mIndex]
	}
	m1 := mIndex + 1
	sIndex := strings.Index(remainingTimeString, "s")
	seconds := remainingTimeString[m1:sIndex]
	return minutes, seconds
}
